﻿using System;
using System.Web;
using Moq;
using NUnit.Framework;

namespace KWatkins.FluentMoqBuilder.Tests
{
	[TestFixture]
	public class ControllerContextBuilderTests : AssertionHelper
	{
		#region WithUrl
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithUrl_String_InvalidUrl(string url)
		{
			MoqBuilder.ControllerContext.WithUrl(url);
		}
		[Test]
		public void WithUrl_String()
		{
			var builder = MoqBuilder.ControllerContext;
			Expect(builder.Object.HttpContext.Request.Url, Is.EqualTo(new Uri("http://localhost/")));

			const string url = "http://www.mrkwatkins.co.uk/";
			Expect(builder.WithUrl(url), Is.EqualTo(builder));
			Expect(builder.Object.HttpContext.Request.Url.ToString(), Is.EqualTo(url));

			// Should throw an exception if we've mocked out the request.
			builder.WithRequest(new Mock<HttpRequestBase>().Object);
			Expect(() => builder.WithUrl(url), Throws.InvalidOperationException);
		}
		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void WithUrl_Uri_InvalidUrl()
		{
			MoqBuilder.ControllerContext.WithUrl((Uri)null);
		}
		[Test]
		public void WithUrl_Uri()
		{
			var builder = MoqBuilder.ControllerContext;
			Expect(builder.Object.HttpContext.Request.Url, Is.EqualTo(new Uri("http://localhost/")));

			Uri url = new Uri("http://www.mrkwatkins.co.uk/");
			Expect(builder.WithUrl(url), Is.EqualTo(builder));
			Expect(builder.Object.HttpContext.Request.Url, Is.EqualTo(url));

			// Should throw an exception if we've mocked out the request.
			builder.WithRequest(new Mock<HttpRequestBase>().Object);
			Expect(() => builder.WithUrl(url), Throws.InvalidOperationException);
		}
		#endregion

		#region WithUrlReferrer
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithUrlReferrer_String_InvalidUrlReferrer(string urlReferrer)
		{
			MoqBuilder.ControllerContext.WithUrlReferrer(urlReferrer);
		}
		[Test]
		public void WithUrlReferrer_String()
		{
			var builder = MoqBuilder.ControllerContext;
			Expect(builder.Object.HttpContext.Request.UrlReferrer, Is.Null);

			const string urlReferrer = "http://www.mrkwatkins.co.uk/";
			Expect(builder.WithUrlReferrer(urlReferrer), Is.EqualTo(builder));
			Expect(builder.Object.HttpContext.Request.UrlReferrer.ToString(), Is.EqualTo(urlReferrer));

			// Should throw an exception if we've mocked out the request.
			builder.WithRequest(new Mock<HttpRequestBase>().Object);
			Expect(() => builder.WithUrlReferrer(urlReferrer), Throws.InvalidOperationException);
		}
		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void WithUrlReferrer_Uri_InvalidUrlReferrer()
		{
			MoqBuilder.ControllerContext.WithUrlReferrer((Uri)null);
		}
		[Test]
		public void WithUrlReferrer_Uri()
		{
			var builder = MoqBuilder.ControllerContext;
			Expect(builder.Object.HttpContext.Request.UrlReferrer, Is.Null);

			Uri urlReferrer = new Uri("http://www.mrkwatkins.co.uk/");
			Expect(builder.WithUrlReferrer(urlReferrer), Is.EqualTo(builder));
			Expect(builder.Object.HttpContext.Request.UrlReferrer, Is.EqualTo(urlReferrer));

			// Should throw an exception if we've mocked out the request.
			builder.WithRequest(new Mock<HttpRequestBase>().Object);
			Expect(() => builder.WithUrlReferrer(urlReferrer), Throws.InvalidOperationException);
		}
		#endregion

		#region WithApplicationPath
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithApplicationPath_InvalidApplicationPath(string applicationPath)
		{
			MoqBuilder.ControllerContext.WithApplicationPath(applicationPath);
		}
		[Test]
		public void WithApplicationPath()
		{
			var builder = MoqBuilder.ControllerContext;
			Expect(builder.Object.HttpContext.Request.ApplicationPath, Is.EqualTo("/"));

			const string applicationPath = "/AppPath";
			Expect(builder.WithApplicationPath(applicationPath), Is.EqualTo(builder));
			Expect(builder.Object.HttpContext.Request.ApplicationPath, Is.EqualTo(applicationPath));

			// Should throw an exception if we've mocked out the request.
			builder.WithRequest(new Mock<HttpRequestBase>().Object);
			Expect(() => builder.WithApplicationPath(applicationPath), Throws.InvalidOperationException);
		}
		#endregion

		#region WithPhysicalApplicationPath
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithPhysicalApplicationPath_InvalidApplicationPath(string applicationPath)
		{
			MoqBuilder.ControllerContext.WithPhysicalApplicationPath(applicationPath);
		}
		[Test]
		public void WithPhysicalApplicationPath()
		{
			var builder = MoqBuilder.ControllerContext;
			Expect(builder.Object.HttpContext.Request.PhysicalApplicationPath, Is.EqualTo(@"c:\inetpub\wwwroot\"));

			const string physicalApplicationPath = @"d:\SomePath";
			Expect(builder.WithPhysicalApplicationPath(physicalApplicationPath), Is.EqualTo(builder));
			Expect(builder.Object.HttpContext.Request.PhysicalApplicationPath, Is.EqualTo(physicalApplicationPath));

			// Should throw an exception if we've mocked out the request.
			builder.WithRequest(new Mock<HttpRequestBase>().Object);
			Expect(() => builder.WithPhysicalApplicationPath(physicalApplicationPath), Throws.InvalidOperationException);
		}
		#endregion
	}
}